package com.zelin.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zelin.common.constant.ProductConstant;
import com.zelin.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.zelin.gulimall.product.dao.AttrGroupDao;
import com.zelin.gulimall.product.dao.CategoryDao;
import com.zelin.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.zelin.gulimall.product.entity.AttrGroupEntity;
import com.zelin.gulimall.product.service.CategoryService;
import com.zelin.gulimall.product.vo.AttrRespVo;
import com.zelin.gulimall.product.vo.AttrVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zelin.common.utils.PageUtils;
import com.zelin.common.utils.Query;

import com.zelin.gulimall.product.dao.AttrDao;
import com.zelin.gulimall.product.entity.AttrEntity;
import com.zelin.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
    @Autowired
    private AttrAttrgroupRelationDao relationDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private AttrGroupDao attrGroupDao;
    @Autowired
    private CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), new QueryWrapper<AttrEntity>());

        return new PageUtils(page);
    }

    /**
     * 2.获取分类规格参数
     *
     * @param params    请求参数
     * @param catelogId 分类id
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId, String attrType) {

        //2.1)根据请求参数得到分页对象
        IPage<AttrEntity> page = new Query<AttrEntity>().getPage(params);
        //2.2)获取到查询包装器对象
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("attr_type", "base".equalsIgnoreCase(attrType) ? 1 : 0);
        if (catelogId != 0) {
            wrapper.eq("catelog_id", catelogId);
        } String key = (String) params.get("key"); if (StringUtils.isNotBlank(key)) {
            //attr_id  attr_name
            wrapper.and(w -> w.eq("attr_id", key).or().like("attr_name", key));
        } IPage ipage = this.page(page, wrapper);
        //2.3）得到每一页数据

        List<AttrEntity> records = ipage.getRecords(); List<AttrRespVo> newList = new ArrayList();
        System.out.println("records = " + records); for (AttrEntity record : records) {
            AttrRespVo vo = new AttrRespVo(); BeanUtils.copyProperties(record, vo);
            //2.3.1）得到分类名
            //① 得到分类id,并查询得到分类名
            Long cateId = record.getCatelogId(); String categoryName = categoryDao.selectById(cateId).getName();
            //② 设置分类名
            vo.setCatelogName(categoryName);
            if (attrType.equalsIgnoreCase("base")) {   //只有规格查询才有分组信息
                //③ 在中间表中根据属性id找到分组id,再根据分组id找到分组名
                Long attrGroupId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", record.getAttrId())).getAttrGroupId();
                //不能使用下面的主键查询，因为attrId,不是中间表的主键，只能使用上面的条件查询
                //Long attrGroupId = relationDao.selectById(record.getAttrId()).getAttrGroupId();
                String attrGroupName = attrGroupDao.selectById(attrGroupId).getAttrGroupName();
                //④ 设置分组名
                vo.setGroupName(attrGroupName);
            }
            //2.3.2)添加到集合中
            newList.add(vo);

            System.out.println("newList = " + newList);
            //2.3.4)为ipage设置新的结果集
            ipage.setRecords(newList);
        }

        PageUtils pageUtils = new PageUtils(ipage); return pageUtils;
    }

    @Transactional
    @Override
    public void saveAttrVo(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity(); BeanUtils.copyProperties(attr, attrEntity);
        //保存AttrEntity
        this.save(attrEntity);
        //保存与AttrGroup的关系

        if (attr.getAttrGroupId() != null) {  //如果有属性的分组信息才在中间表添加内容
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            entity.setAttrId(attrEntity.getAttrId()); entity.setAttrGroupId(attr.getAttrGroupId());
            relationDao.insert(entity);
        }

    }

    /**
     * 2.查询属性详情
     *
     * @param attrId
     * @return
     */
    @Override
    public AttrRespVo attrInfo(Long attrId) {
        //2.1)根据attrId查询AttrEntity对象
        AttrEntity entity = this.getById(attrId);
        //2.2)定义返回值对象AttrRespVo
        AttrRespVo respVo = new AttrRespVo();
        //2.3)拷贝属性
        BeanUtils.copyProperties(entity, respVo);
        //2.4)设置分组属性id
        //2.4.1)在关联的中间表中查询分组id
        AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
        if (relationEntity != null) {  //只有规格才能设置分组名称、分类名称,如果查不到说明是sale属性
            //2.4.2)设置分组名
            String attrGroupName = attrGroupDao.selectById(relationEntity.getAttrGroupId()).getAttrGroupName();
            respVo.setGroupName(attrGroupName);
            respVo.setAttrGroupId(relationEntity.getAttrGroupId());
            //2.4.5)得到分类的名称
            String catelogName = categoryDao.selectById(entity.getCatelogId()).getName();

            //2.4.4)设置分类的名字
            respVo.setCatelogName(catelogName);

        }
        //2.4.2)得到关联路径
        Long[] categoryPath = categoryService.findParentIdByCategoryId(entity.getCatelogId());
        //2.4.3)设置关联路径
        respVo.setCatelogPath(categoryPath);
        System.out.println("respVo = " + respVo);
        return respVo;
    }

    /**
     * 3.修改属性
     *
     * @param attr
     */
    @Override
    public void updateAttr(AttrVo attr) {
        //3.1)定义AttrEntity对象
        AttrEntity attrEntity = new AttrEntity();
        //3.2)拷贝对象
        BeanUtils.copyProperties(attr, attrEntity);
        //3.3)保存
        this.updateById(attrEntity);

        //3.4)修改到中间表
        AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity(); entity.setAttrId(attr.getAttrId());
        entity.setAttrGroupId(attr.getAttrGroupId());

        UpdateWrapper<AttrAttrgroupRelationEntity> updateWrapper = new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId());
        //3.5）查询是否有此记录
        Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
        if (count > 0) {      //数据库有此记录则更新
            relationDao.update(entity, updateWrapper);
        } else {              //数据库没有此记录则添加
            relationDao.insert(entity);
        }

    }
    /**
     * 获取属性分组的关联的所有属性
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> relationAttr(long attrgroupId) {
        //1.在中间表中根据分组id查询出属性id集合
        List<AttrAttrgroupRelationEntity> entities = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        //2.将所有的中间表中的attrId放到一个集合中
        List<Long> attrIds = entities.stream().map(r -> r.getAttrId()).collect(Collectors.toList());
        //3.根据attrIds查询得到所有属性集合
        if(attrIds != null && attrIds.size() > 0) {
            List<AttrEntity> attrEntities = this.baseMapper.selectBatchIds(attrIds);
            return attrEntities;
        }
        return null;

    }

    //获取属性分组没有关联的其他属性
    @Override
    public PageUtils relationNoAttr(Map<String, Object> params, long attrgroupId) {
        //1.根据属性分组id，得到属性分组对象
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        //2.得到此属性分组下的分类id
        Long catelogId = attrGroupEntity.getCatelogId();
        //3.查询当前分类下的所有分组
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        //4.定义所有分组id集合
        List<Long> groupIds = new ArrayList<>();
        for (AttrGroupEntity groupEntity : attrGroupEntities) {
            groupIds.add(groupEntity.getAttrGroupId());
        }
        //5.在属性与属性分组中间表中找出所有分组的属性id
        List<AttrAttrgroupRelationEntity> attrAttrGroudEntity = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", groupIds));
        //6.定义所有分组属性id列表
        List<Long> attrIds = new ArrayList<>();
        for (AttrAttrgroupRelationEntity entity : attrAttrGroudEntity) {
            attrIds.add(entity.getAttrId());
        }
        //7.在属性表中查询不在上述指定属性集合中的属性集合
        IPage<AttrEntity> pg = new Query<AttrEntity>().getPage(params);
        QueryWrapper<AttrEntity> querywrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).notIn("attr_id", attrIds).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) ;
        //条件查询
        String key = (String) params.get("key");
        if(StringUtils.isNotBlank(key)){
            querywrapper.and(w->{
                w.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        //分页查询
        IPage<AttrEntity> page = this.page(pg, querywrapper);
        //返回分页结果
        return new PageUtils(page);
    }

    /**
     * 根据传入的attrId查询searchType=1的所有商品的属性
     * @param attrIds
     * @return
     */
    @Override
    public List<Long> getAttrIdsBySelectType(List<Long> attrIds) {
        List<Long> searchAttrIds = baseMapper.findAttrIdsByAttrIdsAndSelectType(attrIds);
        return searchAttrIds;
    }

}